package cn.mengxw.evcard.config;

import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.mengxw.evcard.entity.*;
import cn.mengxw.evcard.entity.cmd.CommandAdmin;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.meowy.cqp.jcq.entity.CoolQ;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
public class ConfigManage {
  // 初始化
  private static boolean isInit;
  // 开启机器人的群列表
  private static Set<Long> enableRobotSet;
  // 黑名单
  private static Map<Long, Set<Long>> blackLists;
  // 自动禁言列表
  private static Map<Long, Map<String, ForbiddenWordBank>> forbiddenWordBank;
  // 自动回复列表
  private static Map<Long, Map<String, KeywordReply>> keywordReplyMaps;
  // 推荐关键字
  private static Map<Long, Set<String>> recommend;

  // 自动禁言
  private static Map<Long, Integer> automaticForbiddenSpeech;
  // 自动私聊
  private static Map<Long, String> automaticPrivateChat;
  // 自动欢迎
  private static Map<Long, String> greet;
  // 警告次数统计
  private static Map<Long, Map<Long, Integer>> warnNumbers;
  // 机器人管理员
  private static Set<Long> admins;

  public static void init(File file, CoolQ CQ) {

    // excel导入参数
    ImportParams params = new ImportParams();
    params.setTitleRows(0);

    try {
      // 导入开启机器人群列表
      params.setStartSheetIndex(0);
      List<EnableRobotList> enableRobotListts =
          ExcelImportUtil.importExcel(new FileInputStream(file), EnableRobotList.class, params);

      enableRobotSet =
          enableRobotListts.stream()
              .filter(e -> StringUtils.equals(e.getDisjunctor(), "开"))
              .map(EnableRobotList::getGroup)
              .distinct()
              .collect(Collectors.toSet());

      enableRobotSet.forEach(
          group -> {
            CQ.logInfo("群管理初始化", "开启管理的群号为==> " + group);
          });
      CQ.logInfo("配置初始化", "启用群列表初始化完成！");
      // 导入关键字
      params.setStartSheetIndex(1);

      List<KeywordReply> keywordReplys =
          ExcelImportUtil.importExcel(new FileInputStream(file), KeywordReply.class, params);

      Map<Long, List<KeywordReply>> collect =
          keywordReplys.stream()
              .filter(Objects::nonNull)
              .collect(Collectors.groupingBy(KeywordReply::getGroup));
      keywordReplyMaps =
          collect.entrySet().stream()
              .collect(
                  Collectors.toMap(
                      Map.Entry::getKey,
                      v ->
                          v.getValue().stream()
                              .filter(
                                  key ->
                                      LocalDateTime.now()
                                          .isAfter(
                                              LocalDateTime.ofInstant(
                                                  key.getEnableTime().toInstant(),
                                                  ZoneId.systemDefault())))
                              .collect(Collectors.toMap(KeywordReply::getKeyword, val -> val))));
      CQ.logInfo("配置初始化", "关键词回复词库初始化完成！");
      // 加载推荐词库
      recommend =
          collect.entrySet().stream()
              .collect(
                  Collectors.toMap(
                      Map.Entry::getKey,
                      v ->
                          v.getValue().stream()
                              .filter(
                                  k ->
                                      LocalDateTime.now()
                                          .isAfter(
                                              LocalDateTime.ofInstant(
                                                  k.getEnableTime().toInstant(),
                                                  ZoneId.systemDefault())))
                              .filter(
                                  k ->
                                      LocalDateTime.now()
                                          .isBefore(
                                              LocalDateTime.ofInstant(
                                                  k.getOffTime().toInstant(),
                                                  ZoneId.systemDefault())))
                              .map(KeywordReply::getKeyword)
                              .collect(Collectors.toSet())));

      //          .forEach(
      //              e -> {
      //                Suggester suggester = new Suggester();
      //                e.getValue().stream()
      //                    .filter(
      //                        k ->
      //                            LocalDateTime.now()
      //                                .isAfter(
      //                                    LocalDateTime.ofInstant(
      //                                        k.getEnableTime().toInstant(),
      // ZoneId.systemDefault())))
      //                    .filter(
      //                        k ->
      //                            LocalDateTime.now()
      //                                .isBefore(
      //                                    LocalDateTime.ofInstant(
      //                                        k.getOffTime().toInstant(),
      // ZoneId.systemDefault())))
      //                    .forEach(k -> suggester.addSentence(k.getKeyword()));
      //
      //                recommend.put(e.getKey(), suggester);
      //              });
      CQ.logInfo("配置初始化", "推荐词库初始化完成！");
      // 导入加群黑名单
      params.setStartSheetIndex(2);
      List<Blacklist> blacklists =
          ExcelImportUtil.importExcel(new FileInputStream(file), Blacklist.class, params);

      blackLists =
          blacklists.stream()
              .filter(Objects::nonNull)
              .collect(Collectors.groupingBy(Blacklist::getGroup))
              .entrySet()
              .stream()
              .collect(
                  Collectors.toMap(
                      Map.Entry::getKey,
                      v ->
                          v.getValue().stream().map(Blacklist::getQq).collect(Collectors.toSet())));
      CQ.logInfo("配置初始化", "黑名单初始化完成！");
      // 导入禁言词库
      params.setStartSheetIndex(3);
      List<ForbiddenWordBank> forbiddenWordBanks =
          ExcelImportUtil.importExcel(new FileInputStream(file), ForbiddenWordBank.class, params);

      forbiddenWordBank =
          forbiddenWordBanks.stream()
              .filter(Objects::nonNull)
              .collect(Collectors.groupingBy(ForbiddenWordBank::getGroup))
              .entrySet()
              .stream()
              .collect(
                  Collectors.toMap(
                      Map.Entry::getKey,
                      v ->
                          v.getValue().stream()
                              .collect(Collectors.toMap(ForbiddenWordBank::getKeyword, x -> x))));
      CQ.logInfo("配置初始化", "禁言词库初始化完成！");
      // 初始化入群自动禁言
      params.setStartSheetIndex(4);
      List<AutomaticForbiddenSpeech> automaticForbiddenSpeeches =
          ExcelImportUtil.importExcel(
              new FileInputStream(file), AutomaticForbiddenSpeech.class, params);
      automaticForbiddenSpeech =
          automaticForbiddenSpeeches.stream()
              .filter(Objects::nonNull)
              .collect(
                  Collectors.toMap(
                      AutomaticForbiddenSpeech::getGroup, AutomaticForbiddenSpeech::getLength));
      CQ.logInfo("配置初始化", "入群自动禁言库初始化完成！");

      warnNumbers = new HashMap<>(14);
      enableRobotSet.forEach(
          k -> {
            warnNumbers.put(k, new HashMap<Long, Integer>(14));
          });
      CQ.logInfo("配置初始化", "警告统计库初始化完成！");
      // 自动私聊库加载
      params.setStartSheetIndex(5);
      List<AutomaticPrivateChat> automaticPrivateChats =
          ExcelImportUtil.importExcel(
              new FileInputStream(file), AutomaticPrivateChat.class, params);

      automaticPrivateChat =
          automaticPrivateChats.stream()
              .filter(Objects::nonNull)
              .collect(
                  Collectors.toMap(
                      AutomaticPrivateChat::getGroup, AutomaticPrivateChat::getContent));

      CQ.logInfo("配置初始化", "入群自动私聊库初始化完成！");
      // 入群欢迎语
      params.setStartSheetIndex(6);
      List<AutoGreet> autoGreets =
          ExcelImportUtil.importExcel(new FileInputStream(file), AutoGreet.class, params);

      greet =
          autoGreets.stream()
              .filter(Objects::nonNull)
              .collect(Collectors.toMap(AutoGreet::getGroup, AutoGreet::getContent));
      CQ.logInfo("配置初始化", "入群欢迎库初始化完成！");
      // 初始化机器人管理员
      params.setStartSheetIndex(7);
      List<CommandAdmin> commandAdmins =
          ExcelImportUtil.importExcel(new FileInputStream(file), CommandAdmin.class, params);

      admins = commandAdmins.stream().map(CommandAdmin::getAdmin).collect(Collectors.toSet());
      CQ.logInfo("配置初始化", "机器人管理员列表初始化完成！");

      CQ.logInfo("配置文件初始化", "所有配置文件初始化完成！");
      isInit = true;
    } catch (FileNotFoundException e) {
      CQ.logError(e.getMessage(), e.toString());
    } catch (Exception e) {
      CQ.logError(e.getMessage(), e.toString());
      log.error(e.getMessage(), e);
    }
  }

  public static boolean isIsInit() {
    return isInit;
  }

  /**
   * 获取所有的黑名单
   *
   * @param groupId 群号
   * @return
   */
  public static Set<Long> getBlackByGroupId(Long groupId) {
    if (isInit && isEnableRobot(groupId)) {
      Set<Long> qqSet = blackLists.get(groupId);
      return qqSet == null ? new HashSet<Long>() : qqSet;
    }
    return new HashSet<Long>();
  }

  /**
   * 根据QQ号和群号查询是否在黑名单中
   *
   * @param groupId 群号
   * @param qq QQ号码
   * @return
   */
  public static boolean existBlackList(Long groupId, Long qq) {
    if (isEnableRobot(groupId)) {
      return Optional.ofNullable(blackLists.get(groupId))
          .filter(set -> set.contains(qq))
          .isPresent();
    }
    return false;
  }

  /**
   * 根据群号获取所有的禁言关键字
   *
   * @param groupId
   * @return
   */
  public static Map<String, ForbiddenWordBank> getforbiddenWordBankByGroupId(Long groupId) {
    if (isInit && isEnableRobot(groupId)) {
      Map<String, ForbiddenWordBank> wordBank = forbiddenWordBank.get(groupId);
      return wordBank == null ? new HashMap<>() : wordBank;
    }
    return new HashMap<>();
  }

  /**
   * 判断内容中是否包含禁言关键字
   *
   * @param groupId 群号
   * @param content 消息内容
   * @return
   */
  public static ForbiddenWordBank getProhibitoryDuration(Long groupId, String content) {
    if (isInit && isEnableRobot(groupId)) {
      return Optional.ofNullable(forbiddenWordBank)
          .map(m -> m.get(groupId))
          .map(Map::entrySet)
          .map(
              s ->
                  s.stream()
                      .filter(e -> StringUtils.indexOf(content, e.getKey()) > 0)
                      .findAny()
                      .orElse(null))
          .map(e -> e.getValue())
          .orElse(null);
    }
    return null;
  }
  //  private static Map<Long, Map<String, KeywordReply>> keywordReplyMaps;

  /**
   * 根据群号获取自动回复关键字列表
   *
   * @param groupId 群号
   * @return
   */
  public static Map<String, KeywordReply> getKeywordReplysByGroupId(Long groupId) {
    if (isInit && isEnableRobot(groupId)) {
      Map<String, KeywordReply> keywordReplyMap = keywordReplyMaps.get(groupId);
      return keywordReplyMap == null ? new HashMap<>() : keywordReplyMap;
    }
    return new HashMap<>();
  }

  /**
   * 根据群号和关键字查找回复内容
   *
   * @param groupId 群号
   * @param content 消息
   * @return
   */
  public static KeywordReply getKeywordReplys(Long groupId, String content) {
    if (isInit && isEnableRobot(groupId)) {
      return Optional.ofNullable(keywordReplyMaps)
          .map(m -> m.get(groupId))
          .map(m -> m.entrySet())
          .map(
              e ->
                  e.stream()
                      .filter(k -> StringUtils.indexOf(content, k.getKey()) >= 0)
                      .findAny()
                      .orElse(null))
          .map(Map.Entry::getValue)
          .orElse(null);
    }
    return null;
  }

  /**
   * 根据群号获取建议词库
   *
   * @param groupId
   * @return
   */
  public static Set<String> getSuggesterByGroupId(Long groupId) {
    if (isInit && isEnableRobot(groupId)) {
      return recommend.get(groupId);
    }
    return null;
  }

  /**
   * 根据群号获取写禁言时长
   *
   * @param groupId
   * @return
   */
  public static Integer getForbiddenSpeechLength(Long groupId) {
    if (isInit && isEnableRobot(groupId)) {
      return automaticForbiddenSpeech.get(groupId);
    }
    return null;
  }

  /**
   * 根据群号获取欢迎语
   *
   * @param groupId
   * @return
   */
  public static String getGreet(Long groupId) {
    if (isInit && isEnableRobot(groupId)) {
      return greet.get(groupId);
    }
    return null;
  }

  /**
   * 获取私聊信息
   *
   * @param groupId
   * @return
   */
  public static String getPrivateChat(Long groupId) {
    if (isInit && isEnableRobot(groupId)) {
      return automaticPrivateChat.get(groupId);
    }
    return null;
  }

  /**
   * 给指定群的指定用户添加警告
   *
   * @param groupId
   * @param qq
   */
  public static void addWarn(Long groupId, Long qq) {
    Optional<Integer> warn = Optional.ofNullable(warnNumbers.get(groupId)).map(w -> w.get(qq));
    // 如果存在警告则+1
    if (warn.isPresent()) {
      Map<Long, Integer> warnByGroup = warnNumbers.get(groupId);
      warnByGroup.put(qq, warnByGroup.get(qq) + 1);
    } else {
      // 如果不存在警告则
      Map<Long, Integer> warnByGroup = warnNumbers.get(groupId);
      warnByGroup.put(qq, 1);
      warnNumbers.put(groupId, warnByGroup);
    }
  }

  /**
   * 剔除用户，计数器归零
   *
   * @param groupId
   * @param qq
   */
  public static void removeUser(Long groupId, Long qq) {
    if (isInit && isEnableRobot(groupId)) {
      Map<Long, Integer> warnByGroup = warnNumbers.get(groupId);
      warnByGroup.put(qq, 0);
      warnNumbers.put(groupId, warnByGroup);
    }
  }
  /**
   * 获取当前用户被警告的次数
   *
   * @param groupId
   * @param qq
   * @return
   */
  public static Integer getWarnNumbers(Long groupId, Long qq) {
    if (isInit && isEnableRobot(groupId)) {
      return Optional.ofNullable(warnNumbers.get(groupId)).map(w -> w.get(qq)).orElse(0);
    }
    return 0;
  }

  /**
   * 判断这个QQ是否是机器人管理员
   *
   * @param qq
   * @return
   */
  public static boolean isAdmin(Long qq) {
    if (isInit) {
      return admins.contains(qq);
    }
    return false;
  }

  /**
   * 判断群号是开启了机器人
   *
   * @param groupId
   * @return
   */
  public static boolean isEnableRobot(Long groupId) {
    if (isInit) {
      return enableRobotSet.contains(groupId);
    }
    return false;
  }

  /**
   * 获取所有的开启群机器人的列表
   *
   * @return
   */
  public static Set<Long> getenableRobotSet() {
    return enableRobotSet;
  }
}
